﻿using System;
using System.Net;
using System.Net.Sockets;
using System.IO;
using System.Text;
using System.Threading;
using sendfile_server;


namespace socketlib_basic
{
    public class sendfile_client
    {
        private string m_serverIp;
        private int m_serverPort;
        private bool m_Connected = false;   // if connected to server

        public bool Connected
        {
            get { return m_Connected; }
            set { m_Connected = value; }
        }
        private SFClientConnection m_ClientConnection;
        
        public sendfile_client(string serverip, int serverPort)
        {
            m_serverIp = serverip;
            m_serverPort = serverPort;
            m_ClientConnection = new SFClientConnection();

            // connect to server
            try
            {
                //m_tcpClient = new TcpClient(m_serverIp, m_serverPort);
                //m_ns = m_tcpClient.GetStream();
                m_ClientConnection.Connect(m_serverIp, m_serverPort);
                m_Connected = true;
                TraceMsg("connecting to server " + m_serverIp + ": " + m_serverPort);
            }
            catch (SocketException sockex)
            {
                TraceMsg(sockex.Message);
                TraceMsg(sockex.StackTrace);
                m_Connected = false;
                //throw sockex;
            }
            catch (System.Exception ex)
            {
                TraceMsg(ex.Message);
                TraceMsg(ex.StackTrace);
                m_Connected = false;
                //throw ex;
            }
        }

        public int Disconnect()
        {
            int ret = -1;
            if (m_ClientConnection != null)
            {
                m_ClientConnection.Disconnect();
                m_Connected = false;
            }
            return ret;

        }

        /// <summary>
        /// protocol header:
        /// > messaege hader
        /// - filesize : 4 byte int 
        /// - name : 
        /// - data : vaarious length
        /// </summary>
        /// return 1 for successful
        public int SendFile(string filename)
        {
            // validate if file existed 
            FileInfo fi = new FileInfo(filename);
            if ( !fi.Exists)
            {
                TraceMsg("file not existed: " + filename);
                return -1;
            }

            try 
            {
                FileStream fs = new FileStream(filename, FileMode.Open, FileAccess.Read);
                byte[] sendbuf = new byte[fs.Length];
                fs.Read(sendbuf, 0, (int)fs.Length);

                SFMessage msg = new FileDataMessage(filename, sendbuf);
                m_ClientConnection.SendMsg(msg);
                //msg.Dump();
                //foreach (byte b in msg.GetBytes())
                //{
                //    Console.Write("{0:X}, ", b);
                //}
                Console.WriteLine();
                TraceMsg("send file data message to server");
            }
            catch (System.Exception ex)
            {
                TraceMsg(ex.Message);
                TraceMsg(ex.StackTrace);
            }

            //clean up
            return 1;
        }

  
        public void TraceMsg(string msg)
        {
            Console.WriteLine("[{0,3}] - {1} : {2}",
                    Thread.CurrentThread.ManagedThreadId,
                    DateTime.Now.ToString("HH:mm:ss.ffff"), msg);
        }
    }

    class sendfile_client_test
    {

        public static void StartServerAndClientTest()
        {
            StartServerThread();

            StartClientThread();
        }

        private static void StartServerThread()
        {
            Thread serverThread = new Thread(delegate()
            {
                SFServer server = new SFServer(1080);
                server.Start();
            });
            serverThread.Start();


        }

        private static void StartClientThread()
        {
            Thread t1 = new Thread(delegate()
            {
                TestSendFile("phone.txt", "127.0.0.1", 1080);
            });
            t1.Start();
        }
        // i.e. TestSendFile("phone.txt", "127.0.01", 1080)
        public static void TestSendFile(string _f, string _serverip, int _port)
        {
            // f = "phone.txt";
            sendfile_client client = new sendfile_client(_serverip, _port);
            client.SendFile(_f);

        }

        public static void TestInnerThreads(string _f, string _serverip, int _port)
        {
            sendfile_client client = new sendfile_client(_serverip, _port);
            client.SendFile(_f);
        }

        public static void TraceMsg(string msg)
        {
            Console.WriteLine("[{0,3}] - {1} : {2}",
                    Thread.CurrentThread.ManagedThreadId,
                    DateTime.Now.ToString("HH:mm:ss.ffff"), msg);
        }
    }
}